package com.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;


/*======获取 Bean 对象（对象装配）1. 属性注⼊ 2. 构造⽅法注⼊ 3. Setter 注⼊======*/


// 示例：将UserService 注入到UserController1 中

//方式一：属性注入
@Controller
public class UserController1 {

    @Resource
    private UserService userService;

    public void Sayhi(){
        userService.Sayhi("奥特曼");
    }
}


//方式二：构造方法注入
//@Controller
//public class UserController1 {
//
//    private UserService userService;
//
//    @Autowired   //注意： @Resource 不能用来构造方法注入
//    public UserController1(UserService userService) {
//        this.userService = userService;
//    }
//
//    public void Sayhi() {
//        userService.Sayhi("奥利给");
//    }
//}


//方式三：Setter 注入
//@Controller
//public class UserController1 {
//
//    private UserService userService;
//
//    @Autowired
//    public void SetUserService(UserService userService) {
//        this.userService = userService;
//    }
//
//    public void Sayhi(String name) {
//        userService.Sayhi("奥德赛");
//    }
//}




/*案例：同⼀类型多个 @Bean 报错，将User 注入 UserController1*/
//@Controller
//public class UserController1 {
//
//    @Resource
//    private User user;
//
//    public User getUser(){
//        return user;
//    }
//}
//上述代码会报错，因为User类型中有多个 bean对象，改进如下

//一：直接写明 需要注入的bean对象名字
//@Controller
//public class UserController1 {
//
//    @Resource
//    private User user1;
//
//    public User getUser(){
//        return user1;
//    }
//}


//二、使用 使⽤ @Resource(name="XXX")
//@Controller
//public class UserController1 {
//
//    @Resource(name = "user1")
//    private User user;
//
//    public User getUser(){
//        return user;
//    }
//}

//三、使用@Autowired @Qualifier(value = "user2")
//@Controller
//public class UserController1 {
//    @Autowired//此时没有 name 属性
//    @Qualifier(value = "userinfo")
//    private User user;
//
//    public User getUser() {
//        return user;
//    }
//}



/*三种注⼊优缺点分析
*
*1.属性注⼊的优点是简洁，使⽤⽅便；缺点是只能⽤于 IoC 容器，如果是⾮ IoC 容器不可⽤，并且只
有在使⽤的时候才会出现 NPE（空指针异常）
*2.构造⽅法注⼊是 Spring 推荐的注⼊⽅式，它的缺点是当构造方法注⼊参数过多时就会显得⽐较臃肿，但出现这种情况你应该
*考虑⼀下当前类是否符合程序的单⼀职责的设计模式了，它的优点是通⽤性强，在使⽤之前⼀定能把保证注⼊的类不为空，一定初始化过。
*3.Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式，但通⽤性不如构造⽅法，所有 Spring 现版本已经
推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了。
*
 */


/*@Autowired 和 @Resource 的区别
*1.出身不同：@Autowired 来⾃于 Spring，⽽ @Resource 来⾃于 JDK 的注解；
*2.使⽤时设置的参数不同：相⽐于 @Autowired 来说，@Resource ⽀持更多的参数设置，例如 name设置，根据名称获取 Bean
*3.@Autowired支持三种注入，而@Resource 不能支持 构造方法注入
*/